package com.example.administrator.myapplication;


import android.app.Dialog;
import android.app.DownloadManager;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Spinner;

import com.esri.android.map.GraphicsLayer;
import com.esri.android.map.MapView;
import com.esri.android.map.ags.ArcGISFeatureLayer;
import com.esri.android.map.event.OnSingleTapListener;
import com.esri.android.map.event.OnStatusChangedListener;
import com.esri.android.map.popup.Popup;
import com.esri.android.map.popup.PopupContainer;
import com.esri.core.geometry.Envelope;
import com.esri.core.geometry.Point;
import com.esri.core.map.CallbackListener;
import com.esri.core.map.Feature;
import com.esri.core.map.FeatureEditResult;
import com.esri.core.map.FeatureResult;
import com.esri.core.map.FeatureSet;
import com.esri.core.map.Graphic;
import com.esri.core.map.popup.PopupInfo;
import com.esri.core.symbol.SimpleFillSymbol;
import com.esri.core.tasks.SpatialRelationship;
import com.esri.core.tasks.ags.query.Query;
import com.esri.core.tasks.query.QueryParameters;
import com.esri.core.tasks.query.QueryTask;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


public class MainActivity extends AppCompatActivity {
    MapView mMapView;
    ArcGISFeatureLayer mPointFeatureLayer;
    ArcGISFeatureLayer mRoadFeatureLayer;
    ArcGISFeatureLayer mAllFeatureLayer;
    ArcGISFeatureLayer mStatisticLayer;

    GraphicsLayer mGraphicsLayer;
    PopupContainer container;


    String mPointFeatureServiceURL;
    String mRoadFeatureServiceURL;
    String mAllFeatureServiceURL;

    private Point pointClicked;
    // android components
    private LayoutInflater inflator;
    private AttributeListAdapter listAdapter;
    private ListView listView;
    private View listLayout;

    public static final String TAG = "AttributeEditor";
    private static final int ATTRIBUTE_EDITOR_DIALOG_ID = 1;

    MenuItem mBrowseMenuItem = null;
    MenuItem mQueryMenuItem = null;
    MenuItem mEditMenuItem = null;
    MenuItem mStatisticMenuItem = null;
    MenuItem mExportMenuItem = null;

    private class QueryFeatureLayer extends AsyncTask<String, Void, FeatureResult> {
        @Override
        protected FeatureResult doInBackground(String... params) {

            String whereClause = "名称='" + params[0] + "'";

            // Define a new query and set parameters
            QueryParameters mParams = new QueryParameters();
            mParams.setWhere(whereClause);
            mParams.setReturnGeometry(true);
            String [] outFields={"设施金"};
            mParams.setOutFields(outFields);


            // Define the new instance of QueryTask
            QueryTask queryTask = new QueryTask(mAllFeatureServiceURL);
            FeatureResult results;

            try {
                // run the querytask
                results = queryTask.execute(mParams);
                return results;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(FeatureResult results) {

            // Remove the result from previously run query task
            mGraphicsLayer.removeAll();
            container.clearPopups();


            // Envelope to focus on the map extent on the results
            Envelope extent = new Envelope();

            // iterate through results
            for (Object element : results) {
                // if object is feature cast to feature
                if (element instanceof Feature) {
                    Feature feature = (Feature) element;

                    SimpleFillSymbol sms=new SimpleFillSymbol(Color.RED);
                    // convert feature to graphic
                    Graphic graphic = new Graphic(feature.getGeometry(), sms, feature.getAttributes());


                    // merge extent with point
//                    extent.merge((Point) graphic.getGeometry());
                    // add it to the layer
                    mGraphicsLayer.addGraphic(graphic);


                    PopupInfo popupInfo=new PopupInfo();
                    String money=(String)feature.getAttributeValue("设施金");
                    popupInfo.setDescription(money);

                    Popup popup=new Popup(mMapView,popupInfo,feature);
                    container.addPopup(popup);
                }
            }

            // Set the map extent to the envelope containing the result graphics
            mMapView.setExtent(extent, 100);
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        // Retrieve the map and initial extent from XML layout
        mMapView = (MapView) findViewById(R.id.map);


// Get the feature service URL from values->strings.xml
        mPointFeatureServiceURL = this.getResources().getString(R.string.pointsFeatureServiceURL);
// Add Feature layer to the MapView
        mPointFeatureLayer = new ArcGISFeatureLayer(mPointFeatureServiceURL, ArcGISFeatureLayer.MODE.ONDEMAND);
        mMapView.addLayer(mPointFeatureLayer);

        mRoadFeatureServiceURL = this.getResources().getString(R.string.roadFeatureServiceURL);
// Add Feature layer to the MapView
        mRoadFeatureLayer = new ArcGISFeatureLayer(mRoadFeatureServiceURL, ArcGISFeatureLayer.MODE.ONDEMAND);
        mMapView.addLayer(mRoadFeatureLayer);

        mAllFeatureServiceURL = this.getResources().getString(R.string.allFeatureServiceURL);
// Add Feature layer to the MapView
        mAllFeatureLayer = new ArcGISFeatureLayer(mAllFeatureServiceURL, ArcGISFeatureLayer.MODE.ONDEMAND);
        mMapView.addLayer(mAllFeatureLayer);



        mGraphicsLayer = new GraphicsLayer();
        mMapView.addLayer(mGraphicsLayer);

        container=new PopupContainer(mMapView);



        // set up local variables
        inflator = LayoutInflater.from(getApplicationContext());
        listLayout = inflator.inflate(R.layout.list_layout, null);
        listView = (ListView) listLayout.findViewById(R.id.list_view);

        // Create a new AttributeListAdapter when the feature layer is initialized
        if (mAllFeatureLayer.isInitialized()) {
            listAdapter = new AttributeListAdapter(this, mAllFeatureLayer.getFields(), mAllFeatureLayer.getTypes(),
                    mAllFeatureLayer.getTypeIdField());
        } else {
            mAllFeatureLayer.setOnStatusChangedListener(new OnStatusChangedListener() {
                private static final long serialVersionUID = 1L;

                public void onStatusChanged(Object source, STATUS status) {
                    if (status == OnStatusChangedListener.STATUS.INITIALIZED) {
                        listAdapter = new AttributeListAdapter(MainActivity.this, mAllFeatureLayer.getFields(), mAllFeatureLayer
                                .getTypes(), mAllFeatureLayer.getTypeIdField());
                    }
                }
            });
        }



    }

   @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.meun_main, menu);

        // Get the query params menu items.
        mBrowseMenuItem = menu.getItem(0);
        mQueryMenuItem = menu.getItem(1);
        mEditMenuItem = menu.getItem(2);
        mStatisticMenuItem = menu.getItem(3);
        mExportMenuItem = menu.getItem(4);

       mBrowseMenuItem.setChecked(true);
        return true;
    }

   @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle menu item selection.
        switch (item.getItemId()) {
            case R.id.Browse:
                mBrowseMenuItem.setChecked(true);
                mGraphicsLayer.removeAll();
                return true;
            case R.id.Query:
                mQueryMenuItem.setChecked(true);
                final EditText et = new EditText(this);

                // 创建对话框对象
                new AlertDialog.Builder(this).
                                setTitle("搜索").
                                setView(et).
                                setPositiveButton("确定", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                String in = et.getText().toString();
                                new QueryFeatureLayer().execute(in);
                            }
                        }).setNegativeButton("取消", null).
                                create().show();

                return true;
            case R.id.Edit:
                mEditMenuItem.setChecked(true);
                mMapView.getOnSingleTapListener();
                // Set tap listener for MapView
                mMapView.setOnSingleTapListener(new OnSingleTapListener() {
                    private static final long serialVersionUID = 1L;

                    public void onSingleTap(float x, float y) {
                        // convert event into screen click
                        pointClicked = mMapView.toMapPoint(x, y);

                        // build a query to select the clicked feature
                        Query query = new Query();
                        query.setOutFields(new String[]{"*"});
                        query.setSpatialRelationship(SpatialRelationship.INTERSECTS);
                        query.setGeometry(pointClicked);
                        query.setInSpatialReference(mMapView.getSpatialReference());

                        // call the select features method and implement the callbacklistener
                        mAllFeatureLayer.selectFeatures(query, ArcGISFeatureLayer.SELECTION_METHOD.NEW, new CallbackListener<FeatureSet>() {

                            // handle any errors
                            public void onError(Throwable e) {
                                Log.d(TAG, "Select Features Error" + e.getLocalizedMessage());
                            }

                            public void onCallback(FeatureSet queryResults) {
                                if (queryResults.getGraphics().length > 0) {
                                    Log.d(
                                            TAG,
                                            "Feature found id="
                                                    + queryResults.getGraphics()[0].getAttributeValue(mAllFeatureLayer.getObjectIdField()));

                                    // set new data and notify adapter that data has changed
                                    listAdapter.setFeatureSet(queryResults);
                                    listAdapter.notifyDataSetChanged();

                                    // This callback is not run in the main UI thread. All GUI
                                    // related events must run in the UI thread,
                                    // therefore use the Activity.runOnUiThread() method. See
                                    // http://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)
                                    // for more information.
                                    MainActivity.this.runOnUiThread(new Runnable() {

                                        public void run() {

                                            // show the editor dialog.
                                            showDialog(ATTRIBUTE_EDITOR_DIALOG_ID);

                                        }
                                    });
                                }
                            }
                        });
                    }
                });
                return true;
            case R.id.Statistic:
                mStatisticMenuItem.setChecked(true);

                mStatisticLayer = new ArcGISFeatureLayer("https://services8.arcgis.com/FccmMD1UJwe3WP2u/arcgis/rest/services/buildingarea/FeatureServer/0", ArcGISFeatureLayer.MODE.ONDEMAND);

                mMapView.addLayer(mStatisticLayer);

                mAllFeatureLayer.setVisible(false);

                return true;
            case R.id.Export:
                mExportMenuItem.setChecked(true);

                Date date=new Date();
                SimpleDateFormat dateformat1=new SimpleDateFormat("yyyyMMdd_hhmmss");
                String timeString=dateformat1.format(date);
                String path="arcgis1/screenshot";
                String externalPath= Environment.getExternalStorageDirectory().toString();
                String filename=externalPath+"/"+path+"/"+timeString;

                File file_2=new File(externalPath+"/"+path);
                if (!file_2.exists()){
                    System.out.println("path 文件夹 不存在--开始创建");
                    file_2.mkdirs();
                }
                filename=getfilepath(filename);
                System.out.println("获得的filename--"+filename);
                Bitmap bitmap=getViewBitmap(mMapView);

                File file=new File(filename);
                try {
                    FileOutputStream fileOutputStream=new FileOutputStream(file);
                    bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);
                    fileOutputStream.flush();
                    fileOutputStream.close();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected Dialog onCreateDialog(int id) {

        switch (id) {

            case ATTRIBUTE_EDITOR_DIALOG_ID:

                // create the attributes dialog
                Dialog dialog = new Dialog(this);
                listView.setAdapter(listAdapter);
                dialog.setContentView(listLayout);
                dialog.setTitle("Edit Attributes");

                // set button on click listeners, setting as XML attributes doesn't work
                // due to a scope/thread issue
                Button btnEditCancel = (Button) listLayout.findViewById(R.id.btn_edit_discard);
                btnEditCancel.setOnClickListener(returnOnClickDiscardChangesListener());

                Button btnEditApply = (Button) listLayout.findViewById(R.id.btn_edit_apply);
                btnEditApply.setOnClickListener(returnOnClickApplyChangesListener());

                return dialog;
        }
        return null;
    }
    /**
     * Helper method to return an OnClickListener for the Apply button
     */
    private View.OnClickListener returnOnClickApplyChangesListener() {

        return new View.OnClickListener() {

            public void onClick(View v) {

                boolean isTypeField = false;
                boolean hasEdits = false;
                boolean updateMapLayer = false;
                Map<String, Object> attrs = new HashMap<>();

                // loop through each attribute and set the new values if they have
                // changed
                for (int i = 0; i < listAdapter.getCount(); i++) {

                    AttributeItem item = (AttributeItem) listAdapter.getItem(i);
                    String value;

                    // check to see if the View has been set
                    if (item.getView() != null) {

                        // determine field type and therefore View type
                        if (item.getField().getName().equals(mAllFeatureLayer.getTypeIdField())) {
                            // drop down spinner

                            Spinner spinner = (Spinner) item.getView();
                            // get value for the type
                            String typeName = spinner.getSelectedItem().toString();
                            value = FeatureLayerUtils.returnTypeIdFromTypeName(mAllFeatureLayer.getTypes(), typeName);

                            // update map layer as for this featurelayer the type change will
                            // change the features symbol.
                            isTypeField = true;

                        } else if (FeatureLayerUtils.FieldType.determineFieldType(item.getField()) == FeatureLayerUtils.FieldType.DATE) {
                            // date

                            Button dateButton = (Button) item.getView();
                            value = dateButton.getText().toString();

                        } else {
                            // edit text

                            EditText editText = (EditText) item.getView();
                            value = editText.getText().toString();

                        }

                        // try to set the attribute value on the graphic and see if it has
                        // been changed
                        boolean hasChanged = FeatureLayerUtils.setAttribute(attrs, listAdapter.featureSet.getGraphics()[0],
                                item.getField(), value, listAdapter.formatter);

                        // if a value has for this field, log this and set the hasEdits
                        // boolean to true
                        if (hasChanged) {

                            Log.d(TAG, "Change found for field=" + item.getField().getName() + " value = " + value
                                    + " applyEdits() will be called");
                            hasEdits = true;

                            // If the change was from a Type field then set the dynamic map
                            // service to update when the edits have been applied, as the
                            // renderer of the feature will likely change
                            if (isTypeField) {

                                updateMapLayer = true;

                            }
                        }

                        // check if this was a type field, if so set boolean back to false
                        // for next field
                        if (isTypeField) {

                            isTypeField = false;
                        }
                    }
                }

                // check there have been some edits before applying the changes
                if (hasEdits) {

                    // set objectID field value from graphic held in the featureset
                    attrs.put(mAllFeatureLayer.getObjectIdField(), listAdapter.featureSet.getGraphics()[0].getAttributeValue(mAllFeatureLayer.getObjectIdField()));
                    Graphic newGraphic = new Graphic(null, null, attrs);
                    mAllFeatureLayer.applyEdits(null, null, new Graphic[]{newGraphic}, createEditCallbackListener(updateMapLayer));
                }

                // close the dialog
                dismissDialog(ATTRIBUTE_EDITOR_DIALOG_ID);

            }
        };

    }
    /**
     * OnClick method for the Discard button
     */
    private View.OnClickListener returnOnClickDiscardChangesListener() {

        return new View.OnClickListener() {

            public void onClick(View v) {

                // close the dialog
                dismissDialog(ATTRIBUTE_EDITOR_DIALOG_ID);

            }
        };

    }
    /**
     * Helper method to create a CallbackListener<FeatureEditResult[][]>
     *
     * @return CallbackListener<FeatureEditResult[][]>
     */
   private CallbackListener<FeatureEditResult[][]> createEditCallbackListener(final boolean updateLayer) {

        return new CallbackListener<FeatureEditResult[][]>() {

            public void onCallback(FeatureEditResult[][] result) {

                // check the response for success or failure
                if (result[2] != null && result[2][0] != null && result[2][0].isSuccess()) {

                    Log.d(MainActivity.TAG, "Success updating feature with id=" + result[2][0].getObjectId());

                    // see if we want to update the dynamic layer to get new symbols for
                    // updated features
                    if (updateLayer) {

                        mAllFeatureLayer.refresh();

                    }
                }
            }

            public void onError(Throwable e) {

                Log.d(MainActivity.TAG, "error updating feature: " + e.getLocalizedMessage());

            }
        };
    }

    private Bitmap getViewBitmap(MapView v) {

        v.clearFocus();
        v.setPressed(false);

        boolean willNotCache = v.willNotCacheDrawing();
        v.setWillNotCacheDrawing(false);
        int color = v.getDrawingCacheBackgroundColor();
        v.setDrawingCacheBackgroundColor(0);
        if (color != 0) {
            v.destroyDrawingCache();
        }
        v.buildDrawingCache();
        Bitmap cacheBitmap = null;
        while(cacheBitmap == null){
            cacheBitmap = v.getDrawingMapCache(0, 0, v.getWidth(), v.getHeight());
        }
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
        // Restore the view
        v.destroyDrawingCache();
        v.setWillNotCacheDrawing(willNotCache);
        v.setDrawingCacheBackgroundColor(color);
        return bitmap;
    }
    private String getfilepath(String filename) {
        String filestr=filename+".png";
        File file=new File(filestr);
        if (file.exists()){
            filename=getfilepath(filename+"_1");
        }
        else {
            filename=filestr;
        }
        System.out.println("getfilename函数返回----"+filename);
        return filename;
         }
}